import { Feature, Map, Overlay, View } from 'ol' // 引入容器绑定模块和视图模块
import {
    Image as ImageLayer,
    Tile,
    Vector as layersVector,
    VectorTile as VectorTileLayer
} from 'ol/layer' // 瓦片加载器

import {
    Cluster,
    ImageStatic,
    Vector as VectorSource,
    WMTS as sourceWMTS,
    XYZ,
    OSM,
    VectorTile
} from 'ol/source'
import WMTS from 'ol/tilegrid/WMTS'
import { createXYZ } from 'ol/tilegrid'
import { MVT } from 'ol/format'
import { all as LoadingstrategyAll } from 'ol/loadingstrategy'
import { Projection, fromLonLat } from 'ol/proj'
import {
    getCenter,
    getWidth,
    boundingExtent,
    getTopLeft,
    getBottomRight
} from 'ol/extent'
import {
    defaults as InteractionDefault,
    Draw,
    Snap,
    Modify as ModifyInteraction
} from 'ol/interaction'
import { Circle, Point, Polygon, LineString } from 'ol/geom' // 引入XYZ地图格式
import { defaults, defaults as defaultControls, OverviewMap } from 'ol/control'
import Collection from 'ol/Collection.js'
import {
    Circle as StyleCircle,
    Fill,
    Icon,
    Stroke,
    Style,
    Text
} from 'ol/style' // 引入XYZ地图格式
import VectorLayer from 'ol/layer/Vector'
import 'ol/ol.css' // ol提供的css样式（必须引入）
import Modify from 'ol/interaction/Modify'
import { nextTick } from 'vue'

export class OlMap {
    map = null
    selectDrawTool = null
    selectDrawLayer = null
    selectDrawSource = null
    //聚合点对象
    cluster = null
    markerLayers = []
    features = {}
    moverLayersData = []
    Polygonadd = []
    contetnList = []
    girdContent = []
    allPopupList = []
    timerArray = {}
    lineLyers = {}
    lineLayers = []
    //标识是否是绘制
    isDraw = false
    markerLayer = null

    sectorLayers = {} //摄像机照射角度图层

    overviewMapControl = null //地图鹰眼

    accessOverlay = {} //门禁通行记录图层
    /**
     * 初始化地图类
     * @param {String} target 目标元素Id
     */
    constructor(target) {
        this.target = target
        this.onZoneAlarmAnimation = this.onZoneAlarmAnimation.bind(this)
    }

    /**
     * @description: 获取地图中心点
     * @param {*} options
     * @returns
     */
    getMapCoordinates(options) {
        let center
        switch (options.map_type) {
            case 1:
                center = getCenter(options.extend)
                break
            case 2: //百度离线
            case 8:
                center = [options.x, options.y]
                break
        }
        return center
    }
    /**
     * 加载地图
     * @param {array} extend 地图区域坐标数组
     * @param {string} image 地图图层图片路径
     */
    init(options, config, callback, id = 'mapBox') {
        let mapBox = document.getElementById(config.id)
        mapBox.innerHTML = ''
        let mapDiv = document.createElement('div')
        mapBox.id = config.id
        mapBox.style.width = '100%'
        mapBox.style.height = '100%'
        mapBox.style.position = 'relative'
        mapBox.appendChild(mapDiv)
        switch (options.map_type) {
            case 1: //
                // this.map = new Map({
                //     target: config.id,
                //     view: new View({
                //         center: fromLonLat([116.45193744832, 40.251378728948]), // 初始中心点（成都）
                //         zoom: 10, // 初始缩放级别
                //         maxZoom: 18,
                //         minZoom: 3
                //     }),
                //     // 添加底图（可选，用于参考）
                //     layers: [
                //         new Tile({
                //             source: new OSM() // OpenStreetMap底图
                //         })
                //     ]
                // })

                // // 2. 创建MVT矢量瓦片数据源
                // const mvtSource = new VectorTile({
                //     // 瓦片网格：使用Web Mercator投影的XYZ瓦片网格
                //     tileGrid: createXYZ({
                //         maxZoom: 16 // 最大缩放级别，需与MVT服务一致
                //     }),
                //     // MVT瓦片URL模板，替换为你的MVT服务地址
                //     url: 'http://8.137.116.133:30800/api/postgis/gisMap/mvt/selectMultipleMVT?gisMapId=1767830188437016578&z={z}&x={x}&y={y}&token=589ac0ab7974891ed0b0c2ba71f090c9',
                //     // 格式解析器：指定为MVT格式
                //     format: new MVT({
                //         // 可选配置：
                //         // 忽略未知的几何类型
                //         ignoreUnknownGeometries: true
                //         // 若MVT包含多个图层，可指定只加载特定图层
                //         // layers: ['layer-name']
                //     }),
                //     // 瓦片加载策略：根据视图范围加载
                //     strategy: LoadingstrategyAll,
                //     // 跨域设置（如果需要）
                //     crossOrigin: 'anonymous'
                // })

                // // 3. 创建矢量瓦片图层并添加到地图
                // const mvtLayer = new VectorTileLayer({
                //     source: mvtSource,
                //     // 设置样式（根据MVT中的要素属性动态渲染）
                //     style: function (feature) {
                //         // 获取要素属性（根据实际MVT中的属性调整）
                //         const properties = feature.getProperties()

                //         // 示例：根据要素类型设置不同样式
                //         const geometryType = feature.getGeometry().getType()

                //         // 点要素样式
                //         // if (geometryType === 'Point') {
                //         //     return new Style({
                //         //         image: new StyleCircle({
                //         //             radius: 6,
                //         //             fill: new Fill({
                //         //                 color: 'rgba(255, 0, 0, 0.8)'
                //         //             }),
                //         //             stroke: new Stroke({
                //         //                 color: 'white',
                //         //                 width: 2
                //         //             })
                //         //         })
                //         //     })
                //         // }
                //         // 默认样式
                //         return new Style({
                //             stroke: new Stroke({
                //                 color: 'gray',
                //                 width: 1
                //             })
                //         })
                //     }
                // })
                // // 添加MVT图层到地图
                // this.map.addLayer(mvtLayer)
                // break
                var projection = new Projection({
                    code: 'xkcd-image',
                    units: 'pixels',
                    extent: options.extend
                })
                var center = getCenter(options.extend)
                var view = new View({
                    projection: projection, //"EPSG:4326", // 投影坐标系
                    center: center, // 地图中心点
                    zoom: options.zoom, // 地图默认缩放级别
                    maxZoom: options.max_zoom, // 地图最大缩放级别
                    minZoom: options.min_zoom // 地图最小缩放级别
                })
                var layers = [
                    //加载图片
                    new ImageLayer({
                        source: new ImageStatic({
                            url: options.map_file,
                            imageExtent: options.extend,
                            projection: projection
                        })
                    })
                ]
                this.map = new Map({
                    interactions: InteractionDefault({
                        doubleClickZoom: false
                    }),
                    target: config.id,
                    controls: defaultControls({
                        zoom: false
                    }).extend([]),
                    layers: layers,
                    view: view
                })
                //是否开启鹰眼控件
                // 创建鹰眼控件
                this.overviewMapControl = new OverviewMap({
                    // 默认情况下使用相同的层
                    layers: [
                        //加载图片
                        new ImageLayer({
                            source: new ImageStatic({
                                url: options.map_file,
                                imageExtent: options.extend,
                                projection: projection
                            })
                        })
                    ],
                    view: new View({
                        projection: projection, //"EPSG:4326", // 投影坐标系
                        center: center, // 地图中心点
                        zoom: options.zoom, // 地图默认缩放级别
                        maxZoom: options.max_zoom, // 地图最大缩放级别
                        minZoom: options.min_zoom // 地图最小缩放级别
                    }),
                    // 配置鹰眼控件样式
                    className: 'ol-overviewmap ol-custom-overviewmap',
                    collapseLabel: '\u00BB',
                    label: '\u00AB',
                    collapsed: false // 设置为true，默认隐藏
                })

                // 将鹰眼控件添加到地图中
                //this.map.addControl(overviewMapControl)
                break
            case 2: //离线地图
                var projection = new Projection({
                    code: 'EPSG:4326'
                })
                var center = [parseFloat(options.x), parseFloat(options.y)]
                var view = new View({
                    projection: 'EPSG:4326',
                    center: center,
                    zoom: options.zoom, // 地图默认缩放级别
                    maxZoom: options.max_zoom, // 地图最大缩放级别
                    minZoom: options.min_zoom // 地图最小缩放级别
                })
                var layers = [
                    new Tile({
                        source: new XYZ({
                            url: '/mapDownloadFolder/{z}/{x}/{y}.png' //本例中地图瓦片保存在当前目录下的tile文件夹目录下
                        })
                    })
                ]

                this.map = new Map({
                    interactions: InteractionDefault({
                        doubleClickZoom: false
                    }),
                    target: config.id,
                    // controls: defaults().extend([]),
                    controls: defaultControls({
                        zoom: false
                    }).extend([]),
                    layers: layers,
                    view: view
                })
                //鹰眼控件
                this.overviewMapControl = new OverviewMap({
                    // 默认情况下使用相同的层
                    layers: [
                        new Tile({
                            source: new XYZ({
                                url: '/mapDownloadFolder/{z}/{x}/{y}.png' //本例中地图瓦片保存在当前目录下的tile文件夹目录下
                            })
                        })
                    ],
                    view: new View({
                        projection: 'EPSG:4326',
                        center: center,
                        zoom: options.zoom, // 地图默认缩放级别
                        maxZoom: options.max_zoom, // 地图最大缩放级别
                        minZoom: options.min_zoom // 地图最小缩放级别
                    }),
                    collapsed: false
                })

                break
            case 8: //矢量地图
                var center = [options.x * 1, options.y * 1]
                var extent = [
                    options.extend.left * 1,
                    options.extend.bottom * 1,
                    options.extend.right * 1,
                    options.extend.top * 1
                ]
                var projection = new Projection({
                    code: 'EPSG:4326',
                    units: 'degrees',
                    axisOrientation: 'neu',
                    extent: [0, 0, 180, -180]
                })
                var params = {
                    VERSION: '1.0.0',
                    LAYER: options.layers,
                    STYLE: '',
                    TILEMATRIX: [],
                    TILEMATRIXSET: 'EPSG:4326',
                    SERVICE: 'WMTS',
                    FORMAT: 'image/png'
                }

                let projectionExtent = projection.getExtent()
                let size = getWidth(projectionExtent) / 256 //size就是一个像素代表的经纬度
                const resolutions = new Array(22)
                for (let z = 0; z < 22; ++z) {
                    resolutions[z] = size / Math.pow(2, z)
                    params['TILEMATRIX'][z] = params['TILEMATRIXSET'] + ':' + z
                }
                const source = new sourceWMTS({
                    url: options.map_file,
                    layer: params['LAYER'],
                    matrixSet: params['TILEMATRIXSET'],
                    format: params['FORMAT'],
                    projection: projection,
                    tileGrid: new WMTS({
                        tileSize: [256, 256],
                        extent: extent,
                        origin: [-180.0, 90.0],
                        resolutions: resolutions,
                        matrixIds: params['TILEMATRIX'],
                        crossOrigin: 'anonymous'
                    }),
                    style: params['STYLE'],
                    wrapX: true
                })
                var layers = [
                    new Tile({
                        title: 'geoServerMap',
                        source: source,
                        visible: true
                    })
                ]
                var view = new View({
                    center: center,
                    zoom: options.zoom,
                    maxZoom: options.max_zoom, // 地图最大缩放级别
                    minZoom: options.min_zoom, // 地图最小缩放级别
                    resolutions: resolutions,
                    projection: projection,
                    extent: [-180.0, -90.0, 180.0, 90.0]
                })
                this.map = new Map({
                    target: config.id,
                    controls: defaultControls({
                        zoom: false
                    }),
                    layers: layers,
                    view: view
                })
                //鹰眼控件
                this.overviewMapControl = new OverviewMap({
                    // 默认情况下使用相同的层
                    layers: [
                        new Tile({
                            title: 'geoServerMap',
                            source: source,
                            visible: true
                        })
                    ],
                    view: new View({
                        center: center,
                        zoom: options.zoom,
                        maxZoom: options.max_zoom, // 地图最大缩放级别
                        minZoom: options.min_zoom, // 地图最小缩放级别
                        resolutions: resolutions,
                        projection: projection,
                        extent: [-180.0, -90.0, 180.0, 90.0]
                    }),
                    collapsed: false
                })
                break
        }

        var dragging = false
        var startPoint = null
        var that = this
        //右键菜单 属性
        this.map.getViewport().oncontextmenu = function () {
            return false
        }
        //添加地图的点击事件 点位和 点击地图事件
        this.map.on('click', (e) => {
            let pixel = e.pixel
            let features = this.map.forEachFeatureAtPixel(pixel, (feature) => {
                //根据像素坐标获取右键选中的地图要素
                return feature
            })

            if (!features) {
                //代表是地图的点击方法
                this.clickMap({ e })
                return
            }
            //地图上资源的点击事件
            let type = features.getGeometry().getType()
            switch (type) {
                case 'Point': //点位的点击事件
                    //如果点击的是聚合点  不做处理
                    if (!('features' in features.values_)) {
                        return
                    }
                    if (features.values_.features?.length > 1) {
                        return
                    }
                    dragging = true
                    startPoint = e.coordinate
                    if (!features.values_.features) {
                        return
                    }
                    let tempFeature = features.values_.features[0]
                    let data = tempFeature.values_.data
                    let i
                    if (tempFeature) {
                        i = this.markerLayers.findIndex((o) => {
                            return o.data.id === data.id
                        })
                    }
                    //回传给页面上的事件处理
                    this.clickMarker({
                        type: type,
                        feature_: tempFeature,
                        geom_: tempFeature.getGeometry(),
                        data_: data,
                        index_: i
                    })
                    break
                case 'Polygon': //点击网格的事件
                    break
                    this.features = features
                    // this.girdContent = features.values_.data?features.values_.data.cotent[0]:  features.getGeometry().getCoordinates()[0]
                    //回传给页面的方法
                    this.clickGird(this.features)
                    //给网格添加绘制功能
                    //开始监听网格的编辑事件
                    // 将新的要素添加到图层中
                    let modify = new Modify({
                        features: new Collection([this.features]),
                        pixelTolerance: 5
                    })

                    // 创建一个新的要素，表示辅助线
                    this.map.addInteraction(modify)

                    let startMove = false

                    //画一条横线
                    const lineObj = new Feature({
                        geometry: new LineString([
                            [0, 0],
                            [70, 70]
                        ])
                    })

                    //实例化一个矢量图层Vector作为绘制层
                    var source1 = new VectorSource({
                        features: [lineObj]
                    })
                    //创建一个图层
                    var vector11 = new VectorLayer({
                        source: source1
                    })
                    //画一条竖线
                    const verticalLine = new Feature({
                        geometry: new LineString([
                            [0, 0],
                            [70, 70]
                        ])
                    })

                    //实例化一个矢量图层Vector作为绘制层
                    var verticalLineSource = new VectorSource({
                        features: [verticalLine]
                    })
                    //创建一个图层
                    var verticalLineVector = new VectorLayer({
                        source: verticalLineSource
                    })
                    var condition = this.map.getCoordinateFromPixel(pixel)
                    // console.log(this.girdContent);

                    modify.on('modifystart', (evt) => {
                        var condition = this.map.getCoordinateFromPixel(pixel)
                        var feature = evt.features.array_[0]
                        let featureObj = { feature }
                        let coordinates = featureObj.feature
                            .getGeometry()
                            .getCoordinates()
                        this.girdContent = coordinates[0]

                        this.map.addLayer(verticalLineVector)
                        this.map.addLayer(vector11)
                    })
                    this.map.on('pointermove', ({ pixel }) => {
                        var condition = this.map.getCoordinateFromPixel(pixel)
                        lineObj.setGeometry(
                            new LineString([
                                [0, condition[1]],
                                [1200, condition[1]]
                            ])
                        )
                        lineObj.setStyle(
                            new Style({
                                //边线颜色
                                stroke: new Stroke({
                                    color: '#3333ff',
                                    width: 1
                                })
                            })
                        )
                        verticalLine.setGeometry(
                            new LineString([
                                [condition[0], 0],
                                [condition[0], 800]
                            ])
                        )
                        verticalLine.setStyle(
                            new Style({
                                //边线颜色
                                stroke: new Stroke({
                                    color: '#3333ff',
                                    width: 1
                                })
                            })
                        )
                        for (var i = 0; i < this.girdContent.length; i++) {
                            //过滤掉当前拖动的点
                            if (
                                this.girdContent[i][0] == condition[0] &&
                                this.girdContent[i][1] == condition[1]
                            ) {
                                continue
                            }
                            //垂直对齐
                            if (this.girdContent[i][0] == condition[0]) {
                                verticalLine.setStyle(
                                    new Style({
                                        //边线颜色
                                        stroke: new Stroke({
                                            color: '#ff0000',
                                            width: 3
                                        })
                                    })
                                )
                            }
                            //水平对齐
                            if (this.girdContent[i][1] == condition[1]) {
                                lineObj.setStyle(
                                    new Style({
                                        //边线颜色
                                        stroke: new Stroke({
                                            color: '#ff0000',
                                            width: 3
                                        })
                                    })
                                )
                            }
                        }
                        // //比对当前网格 已经划过的线  是否水平对齐
                        // console.log('features', features)
                        // if (startMove) {
                        //     // 绘制网格
                        //     this.drawGrid(pixel)
                        // }
                    })
                    modify.on('modifyend', (e) => {
                        var feature = e.features.array_[0]
                        let featureObj = { feature }
                        let coordinates = featureObj.feature
                            .getGeometry()
                            .getCoordinates()
                        this.girdContent = coordinates[0]
                        this.map.removeLayer(verticalLineVector)
                        this.map.removeLayer(vector11)

                        // this.features.setGeometry(geometry)
                        // console.log('modifyend_1', featureObj.feature.getGeometry().getCoordinates())
                        // console.log(e.feature.getGeometry().getCoordinates())
                        // setLine(false)
                        // var feature = e.features.array_[0]
                        this.gridModifyEnd({ feature })
                    })
                    break
                case 'Circle': //探测区域的
                    this.features = features
                    this.clickGird(this.features)
                    break
                case 'LineString': //线的点击事件
                    console.log('LineString', features.values_)
                    // this.clickLineFeatures(features)
                    this.clickMarker({
                        data_: {
                            id: features.values_.marker_id
                        }
                    })
                    break
            }
        })

        //监听地图缩放 事件 缩放到最大层级 需要展开的聚合点
        this.map.getView().on('change:resolution', function (event) {
            if (that.cluster) {
                if (
                    that.map.getView().getZoom() ==
                    that.map.getView().getMaxZoom()
                ) {
                    that.cluster.setDistance(0)
                } else {
                    that.cluster.setDistance(50)
                }
            }
            // console.log('地图缩放', that.map.getOverlays())
            // that.map.getOverlays().clear()
            that.closeAlarmPopup()
            // console.log('地图缩放', that.deviceAlarmNum)
            setTimeout(() => {
                that.test(that.deviceAlarmNum)
            }, 1000)
        })

        //监听地图移动事件
        // this.map.on('move', function (e) { })

        this.map.on('pointermove', (e) => {
            this.markerCenter = e.coordinate
        })
        //添加点位/网格 需要在 地图加载完成后执行  所以需要进行回调
        callback(this.map)

        // this.map.on('moveend', e => {
        //     that.markerOrCluster = []
        //     that.alarmClusterArr = []
        //     if (that.cluster) {
        //         var markersData = that.cluster.features
        //         markersData.forEach(function (item) {
        //             if (item.values_.features.length == 1) {
        //                 var device_id = 'device' + item.values_.features[0].values_.data.device_id
        //                 that.markerOrCluster[device_id] = [item.values_.features[0].values_.data.x, item.values_.features[0].values_.data.y]
        //             } else {
        //                 var clusterArr = []
        //                 clusterArr[0] = [item.values_.geometry.flatCoordinates[0], item.values_.geometry.flatCoordinates[1], 0]
        //                 var clusterPoint = item.values_.features
        //                 clusterPoint.forEach(function (iitem) {
        //                     clusterArr[iitem.values_.data.device_id] = []
        //                     clusterArr[0][2] += that.deviceAlarmNum[iitem.values_.data.device_id + ''] || 0
        //                 })
        //                 that.alarmClusterArr.push(clusterArr)
        //             }
        //         })
        //         that.addPopup()
        //     }
        // })
        // var dragging = false
        // var startPoint = null

        // const Line = new Feature({
        //     geometry: new LineString([
        //         [0, 0],
        //         [70, 70],
        //     ])
        // });

        // //实例化一个矢量图层Vector作为绘制层
        // var source1 = new VectorSource({
        //     features: [Line]
        // });
        // //创建一个图层
        // var vector11 = new VectorLayer({
        //     source: source1
        // });
        // this.map.addLayer(vector11)
    }
    /**
     * 防区绘制结束
     * @param {*} e
     */
    drawZonesEnd(e) {}
    /**
     * 像地图添加地图绘制控件
     * @param {*} data
     */
    initDraw(data) {
        const _this = this
        this.markerLayers.forEach((item) => {
            this.map.removeLayer(item.layer)
        })
        this.markerLayers = []
        this.isDraw = true
        // 创建一个Vector图层，用于存储绘制的图形
        const vectorLayer = new layersVector({
            source: new VectorSource()
        })

        // 添加Vector图层到地图中
        this.map.addLayer(vectorLayer)

        // 创建Draw交互控件，绘制LineString类型的图形
        const drawInteraction = new Draw({
            source: vectorLayer.getSource(),
            type: 'LineString' // 选择绘制线条
        })

        // 启用Draw控件
        this.map.addInteraction(drawInteraction)

        // 绘制结束后，获取线条的坐标（可选）
        drawInteraction.on('drawend', function (event) {
            const feature = event.feature
            // 设定绘制结束后的新样式
            const newStyle = new Style({
                stroke: new Stroke({
                    color: 'red', // 修改为红色
                    width: 4 // 修改线宽为4
                })
            })
            // 设置绘制完成后的新样式
            feature.setStyle(newStyle)
            const geometry = feature.getGeometry()
            const coordinates = geometry.getCoordinates() // 获取线条的坐标数组
            _this.isDraw = false
            //绘制完成后移除交互
            _this.map.removeInteraction(drawInteraction)
            _this.drawZonesEnd({ data: data, coordinates: coordinates })
        })
    }
    // 开启选区工具
    createSelectionTool(callback) {
        // 添加绘制矩形的交互功能
        this.selectDrawSource = new VectorSource()
        this.selectDrawLayer = new VectorLayer({
            source: this.selectDrawSource,
            style: new Style({
                fill: new Fill({
                    color: 'rgba(0, 255, 0, 0.2)' // 矩形填充颜色
                }),
                stroke: new Stroke({
                    color: '#00FF00', // 矩形边框颜色
                    width: 2
                })
            })
        })

        this.map.addLayer(this.selectDrawLayer)

        this.selectDrawTool = new Draw({
            source: this.selectDrawSource,
            type: 'Circle',
            geometryFunction: function (coordinates, geometry) {
                // 计算矩形的边界框
                const extent = boundingExtent([coordinates[0], coordinates[1]])
                // 手动创建矩形的坐标数组
                const topLeft = getTopLeft(extent)
                const bottomRight = getBottomRight(extent)
                const rectCoordinates = [
                    [
                        [topLeft[0], topLeft[1]],
                        [bottomRight[0], topLeft[1]],
                        [bottomRight[0], bottomRight[1]],
                        [topLeft[0], bottomRight[1]],
                        [topLeft[0], topLeft[1]]
                    ]
                ]

                // 创建矩形几何对象
                const rect = new Polygon(rectCoordinates)

                // 返回矩形的几何对象
                if (!geometry) {
                    geometry = rect
                } else {
                    geometry.setCoordinates(rect.getCoordinates())
                }

                return geometry
            }
        })

        this.selectDrawTool.on('drawstart', (event) => {
            this.selectDrawSource
                .getFeatures()
                .forEach((feature) =>
                    this.selectDrawSource.removeFeature(feature)
                )
        })

        // 监听绘制结束事件
        this.selectDrawTool.on('drawend', (event) => {
            const geometry = event.feature.getGeometry()
            // console.log('绘制结束，矩形几何：', geometry);
            // 在这里可以处理绘制结束后的逻辑
            // 获取矩形的边界框（extent）
            const extent = geometry.getExtent()

            // 计算矩形的四个角坐标
            const topLeft = getTopLeft(extent)
            const bottomRight = getBottomRight(extent)
            const coordinates = [
                topLeft, // 左上角
                [bottomRight[0], topLeft[1]], // 右上角
                bottomRight, // 右下角
                [topLeft[0], bottomRight[1]] // 左下角
            ]

            // console.log('绘制结束，矩形的四个角坐标：', coordinates)
            this.map.removeInteraction(this.selectDrawTool) // 移除绘制工具
            callback?.(coordinates)
        })

        this.map.addInteraction(this.selectDrawTool)
    }

    // 移除选区工具
    removeSelectionTool() {
        this.map.removeLayer(this.selectDrawLayer)
        this.map.removeInteraction(this.selectDrawTool)
    }

    // 清空已渲染的选区
    clearSelectionTool() {
        this.selectDrawSource
            .getFeatures()
            .forEach((feature) => this.selectDrawSource.removeFeature(feature))
    }

    createLineLayers() {}

    /**
     * 根据指定的 key-value 查找 layer
     *
     * @param {string} key - layer.data 中的 key
     * @param {any} value - layer.data 中的 value
     * @returns {Object|undefined} - Map.Layer 对象
     */
    findLayer(key, value) {
        const layers = this.map.getLayers().getArray()

        return layers.find((layer) => layer.get(key) == value)
    }

    /**
     * 开始初始化绘制防区
     * @param {*} data
     */
    initDrawZones(data, type) {
        data.forEach((item) => {
            const coordinates = item.extend
            // 创建 LineString 几何对象
            const lineString = new LineString(coordinates)
            // 创建一个要素，并设置其几何对象为 LineString
            const lineFeature = new Feature({
                geometry: lineString
            })

            lineFeature.setId(item.id)
            lineFeature.set('marker_id', item.id)
            lineFeature.set('id', item.id)
            lineFeature.set('device_id', item.device_id)
            lineFeature.set('device_name', item.name)
            lineFeature.set('node_id', item.type)
            lineFeature.set('alarm', item.alarm)
            const middleCoordinate = lineString.getCoordinateAt(0.5)
            const lineStyle = new Style({
                stroke: new Stroke({
                    color: '#00cc44', // 线条颜色
                    width: 5 // 线条宽度
                }),
                text: new Text({
                    text: item.name, // 显示的文字
                    font: 'bold 20px Arial', // 字体样式
                    fill: new Fill({
                        color: 'red' // 文字颜色
                    }),
                    stroke: new Stroke({
                        color: 'white', // 文字边框颜色
                        width: 2
                    }),
                    textAlign: 'center', // 文字对齐方式
                    textBaseline: 'middle', // 文字垂直对齐方式
                    offsetX: 0, // X轴偏移量
                    offsetY: 0,
                    geometry: new Point(middleCoordinate) // 设置文字的位置为线条中点
                })
            })

            // 创建矢量图层
            const vectorSource = new VectorSource({
                features: [lineFeature]
            })

            const layer = new VectorLayer({
                source: vectorSource,
                style: lineStyle
            })

            layer.setNameClose = (layer) => {
                const newStyle = {
                    stroke: new Stroke({
                        color: '#00cc44', // 线条颜色
                        width: 5 // 线条宽度
                    }),
                    text: null
                }
                layer.setStyle(new Style(newStyle))
            }
            layer.setNameOpen = (layer) => {
                const newStyle = {
                    stroke: new Stroke({
                        color: '#00cc44', // 线条颜色
                        width: 5 // 线条宽度
                    }),
                    text: new Text({
                        text: item.name, // 显示的文字
                        font: 'bold 20px Arial', // 字体样式
                        fill: new Fill({
                            color: 'red' // 文字颜色
                        }),
                        stroke: new Stroke({
                            color: 'white', // 文字边框颜色
                            width: 2
                        }),
                        textAlign: 'center', // 文字对齐方式
                        textBaseline: 'middle', // 文字垂直对齐方式
                        offsetX: 0, // X轴偏移量
                        offsetY: 0,
                        geometry: new Point(middleCoordinate) // 设置文字的位置为线条中点
                    })
                }
                layer.setStyle(new Style(newStyle))
            }

            // 防区米数
            const [min, max] = Array.isArray(item.meters) ? item.meters : [0, 0]

            layer.set('zone_meter', max - min || 0)
            // alarm_meter 中的数据格式 {id: data.event_id, meter: data.meter}
            layer.set('alarm_meter', [])
            layer.set('name', item.name)
            layer.set('middleCoordinate', middleCoordinate)
            layer.set('alarmStep', (item.alarm > 0) | 0)
            layer.set('alarm', item.alarm | 0)
            layer.set('device_id', item.device_id)
            this.lineLayers[item.device_id] = layer

            // // 修改控件：用于编辑线段
            // var modify = new ModifyInteraction({
            //     source: vectorSource // 修改时的图层数据源
            // })
            // this.map.addInteraction(modify)
            // // 监听编辑结束事件
            // modify.on('modifyend', (event) => {
            //     const modifiedFeatures = event.features.getArray() // 获取所有被修改的要素
            //     modifiedFeatures.forEach((feature) => {
            //         console.log('编辑结束，已修改的要素 ID:', feature)
            //         // 在这里处理编辑结束后的逻辑，例如保存数据、更新状态等
            //         // 例如，更新 feature 中的某些属性
            //         // feature.set('updated', true);
            //     })
            // })

            this.map.addLayer(layer)

            this.onZoneAlarmAnimation(layer)
            //地图管理时的加载防区 不计算报警点数
            if (type == 1) {
                return
            }

            // 通过 layer.data.alarm 判断是否报警
            layer.on('propertychange', (e) => {
                if (e.key == 'alarm' || e.key == 'alarmStep') {
                    this.onZoneAlarmAnimation(layer)
                }
            })
        })
    }

    // 防区线的报警动画
    onZoneAlarmAnimation(layer) {
        // console.log('🚀 ~ OlMap ~ onZoneAlarmAnimation ~ layer:', layer)
        // const layer = e.target
        const alarm = layer.get('alarm') | 0
        const step = layer.get('alarmStep') | 0

        const color = step == 0 ? '#00cc44' : '#f02828'

        layer.setStyle(
            new Style({
                stroke: new Stroke({
                    color: color,
                    width: 5
                }),
                text: new Text({
                    text: layer.get('name'), // 显示的文字
                    font: 'bold 20px Arial', // 字体样式
                    fill: new Fill({
                        color: 'red' // 文字颜色
                    }),
                    stroke: new Stroke({
                        color: 'white', // 文字边框颜色
                        width: 2
                    }),
                    textAlign: 'center', // 文字对齐方式
                    textBaseline: 'middle', // 文字垂直对齐方式
                    offsetX: 0, // X轴偏移量
                    offsetY: 0,
                    geometry: new Point(layer.get('middleCoordinate')) // 设置文字的位置为线条中点
                })
            })
        )

        if (!alarm) {
            return
        }

        setTimeout(() => {
            layer.set('alarmStep', !step | 0)
        }, 800)
        // console.log('🚀 ~ OlMap ~ onZoneAlarmAnimation ~ layer:', layer.get('device_id'), alarm)
    }

    /**
     * 添加防区中的报警点位
     * 点位 feature 以 device_id 为索引 id
     * @param data
     * @param data.device_id 设备 id
     * @param data.event_id  事件 id
     * @param data.meters  报警米数
     */
    addZoneAlarm(data) {
        const layer = this.findLayer('device_id', data.device_id)

        if (!layer) {
            console.warn(`未找到 device_id 为 ${data.device_id} 的防区`)
            return
        }

        const layerAlarm = layer.get('alarm') | 0
        const zoneMeter = layer.get('zone_meter')

        // 没有报警米数或者数据异常，认为时防区报警，只处理防区报警数
        if (!zoneMeter || !data.meters || zoneMeter < data.meters) {
            layer.set('alarm', layerAlarm + 1)
            console.warn(
                `防区 ${data.device_id} 的报警米数 ${data.meters} 超过防区米数 ${zoneMeter}`
            )
            return
        }

        const alarmMeters = layer.get('alarm_meter') // 数据为 [{ id: data.event_id, meter: data.meter }]
        const alarmPointData = alarmMeters.find((o) => o.id == data.event_id)
        const source = layer.getSource()
        const prevFeature = source.getFeatureById(data.event_id)

        if (alarmPointData) {
            // 更新报警点位的米数
            alarmPointData.meter = data.meters

            if (prevFeature) {
                source.removeFeature(prevFeature)
            }
        } else {
            layer.set('alarm', layerAlarm + 1)
            layer.set('alarm_meter', [
                ...alarmMeters,
                { id: data.event_id, meter: data.meters }
            ])
        }

        const lineFeature = source.getFeatureById(data.device_id)

        // 找不到防区时，直接退出
        if (!lineFeature) {
            console.warn(`未找到 device_id 为 ${data.device_id} 的防区`)
            return
        }

        const currentCoordinate = lineFeature
            .getGeometry()
            .getCoordinateAt(data.meters / zoneMeter)

        const alarmFeature = new Feature({
            geometry: new Point(currentCoordinate)
        })

        alarmFeature.setId(data.event_id)
        alarmFeature.setStyle(
            new Style({
                image: new StyleCircle({
                    radius: 6,
                    fill: new Fill({ color: 'red' }),
                    stroke: new Stroke({
                        color: 'rgba(245, 108, 108, 0.7)',
                        width: 20
                    })
                }),
                text: new Text({
                    text: `${data.meters} 米`, // 显示的文字
                    font: 'bold 12px Arial', // 字体样式
                    fill: new Fill({
                        color: 'red' // 文字颜色
                    }),
                    stroke: new Stroke({
                        color: 'white', // 文字边框颜色
                        width: 2
                    }),
                    textAlign: 'center', // 文字对齐方式
                    textBaseline: 'middle', // 文字垂直对齐方式
                    offsetX: 0, // X轴偏移量
                    offsetY: -18,
                    geometry: new Point(currentCoordinate)
                })
            })
        )

        source.addFeature(alarmFeature)
    }

    /**
     * 移除防区中的报警点位
     * 点位 feature 以 device_id 为索引 id
     * @param data
     * @param data.device_id 设备 id
     * @param data.event_id  事件 id
     */
    removeZoneAlarm(data) {
        const layer = this.findLayer('device_id', data.device_id)

        if (!layer) {
            console.warn(`未找到 device_id 为 ${data.device_id} 的防区`)
            return
        }

        const layerAlarm = layer.get('alarm') | 0
        const alarmMeters = layer.get('alarm_meter') // 数据为 [{ id: data.event_id, meter: data.meters }]
        const source = layer.getSource()
        const prevFeature = source.getFeatureById(data.event_id)

        if (prevFeature) {
            source.removeFeature(prevFeature)
        }

        if (layerAlarm >= 1) {
            layer.set('alarm', layerAlarm - 1)
        }

        layer.set(
            'alarm_meter',
            alarmMeters.filter((o) => o.id != data.event_id)
        )
    }

    createLine(data) {
        data.forEach((item) => {
            const coordinates = []
            item.line.forEach((elment) => {
                coordinates.push([elment.x, elment.y])
            })
            // 创建 LineString 几何对象
            const lineString = new LineString(coordinates)
            // 创建一个要素，并设置其几何对象为 LineString
            const lineFeature = new Feature({
                geometry: lineString
            })
            lineFeature.set('device_id', item.device_id)
            lineFeature.set('device_name', item.device_name)
            lineFeature.set('node_id', item.node_id)
            lineFeature.set('alarm', item.alarm)
            const layer = new VectorLayer({
                source: new VectorSource({
                    features: [lineFeature]
                }),
                style: new Style({
                    stroke: new Stroke({
                        color: '#00cc44',
                        width: 5
                    })
                })
            })
            layer.set('alarm', item.alarm)
            this.lineLyers[item.device_id] = layer
            this.map.addLayer(layer)
            if (item.alarm > 0) {
                //正在发生报警
                let step = {
                    step: 0,
                    timer: null
                }
                this.timerArray[item.device_id] = step
                this.timerArray[item.device_id].timer = setInterval(() => {
                    if (this.timerArray[item.device_id].step % 2 == 0) {
                        layer.setStyle(
                            new Style({
                                stroke: new Stroke({
                                    color: '#00cc44',
                                    width: 5
                                })
                            })
                        )
                    } else {
                        layer.setStyle(
                            new Style({
                                stroke: new Stroke({
                                    color: 'red',
                                    width: 5
                                })
                            })
                        )
                    }
                    this.timerArray[item.device_id].step++
                }, 1000)
            }
        })
    }
    /**
     * 防区报警处理方法
     * @param {*} item
     */
    guardAlarmFunc(item) {
        var _this = this
        var layer = this.lineLyers[item.guard_id] || null
        if (!layer) {
            return
        }
        let num = layer.get('alarm')
        if (this.timerArray[item.guard_id]) {
            //如果当前报警的防区已经是报警状态,数量+1
            layer.set('alarm', num * 1 + 1)
            this.lineLyers[item.guard_id] = layer
            return
        }
        layer.set('alarm', 1)
        let step = {
            step: 0,
            timer: null
        }
        this.lineLyers[item.guard_id] = layer
        this.timerArray[item.guard_id] = step
        this.timerArray[item.guard_id].timer = setInterval(() => {
            if (this.timerArray[item.guard_id].step % 2 == 0) {
                layer.setStyle(
                    new Style({
                        stroke: new Stroke({
                            color: '#00cc44',
                            width: 5
                        })
                    })
                )
            } else {
                layer.setStyle(
                    new Style({
                        stroke: new Stroke({
                            color: 'red',
                            width: 5
                        })
                    })
                )
            }
            this.timerArray[item.guard_id].step++
        }, 1000)
    }
    /**
     * 振动单元消警后 报警防区的处理方式
     * @param {*} item
     * @returns
     */
    closeGuardAlarm(item) {
        var layer = this.lineLyers[item.guard_id] || null
        if (!layer) {
            return
        }
        if (!this.timerArray[item.guard_id]) {
            return
        }
        let num = layer.get('alarm')
        if (num <= 1) {
            layer.set('alarm', 0)
            clearInterval(this.timerArray[item.guard_id].timer)
            // this.timerArray.splice(item.guard_id, 1)
            delete this.timerArray[item.guard_id]
            // this.map.removeLayer(layer)
            layer.setStyle(
                new Style({
                    stroke: new Stroke({
                        color: '#00cc44',
                        width: 5
                    })
                })
            )
            return
        }
        layer.set('alarm', num * 1 - 1)
        this.lineLyers[item.guard_id] = layer
        return
    }
    /**
     * @descriptions 创建点位图标
     * @param {*} item
     * @returns
     */
    createMarkerIcon(item) {
        const baseSVG = `<svg width="36" height="36" viewBox="0 0 56 56" xmlns="http://www.w3.org/2000/svg">
                <circle fill="${
                    item.color || '#fff'
                }" opacity="0.6" cx="28" cy="28" r="28"/>
                <circle fill="${
                    item.color || '#2564fc'
                }" cx="28" cy="28" r="25"/>
                <path fill="#fff" d="${item.icon}"/>
            </svg>`
        return {
            opacity: 1, //透明度
            scale: 1, //缩放比例
            src: 'data:image/svg+xml;utf-8,' + encodeURIComponent(baseSVG),
            anchor: [18, 18], //锚点
            size: [36, 36],
            anchorOrigin: 'bottom-left', //锚点源
            anchorXUnits: 'pixels', //锚点X值单位
            anchorYUnits: 'pixels', //锚点Y值单位
            offsetOrigin: 'bottom-left', //偏移原点
            rotation: item.rotation || 0 //图标旋转角度（弧度值）
        }
    }
    /**
     * @descriptions 创建点位文本
     * @param {*} item
     * @returns
     */
    createMarkerText(item) {
        return {
            textAlign: 'center', //位置
            padding: [5, 8, 5, 8],
            textBaseline: 'middle', //基准线
            font: 'bold 12px 微软雅黑', //'normal 12px 微软雅黑', //文字样式
            text: item.device_name || item.name || '', //文本内容
            offsetY: -22,
            fill: {
                color: item.color || '#2564fc'
            }
        }
    }
    /**
     * 创建聚合点的方法
     * @param {*} data
     */
    createClusterMarker(markers) {
        this.sourceABC = new VectorSource()
        let source = new VectorSource()
        const camera_types = [47, 219]
        markers.forEach((item) => {
            //创建点位对象
            var style = {
                image: this.createMarkerIcon(item),
                text: this.createMarkerText(item)
            }
            var obj = objectMerge(
                {
                    point: [],
                    style: style
                },
                item
            )
            //点位坐标
            let coordinates = [item.x, item.y]
            let feature = new Feature({
                geometry: new Point(coordinates, 'XY'),
                data: item
            })

            feature.setVisibleClose = (feature) => {
                const point = this.markerLayers.find(
                    (o) => o.data.device_id == item.device_id
                )
                point.layer.set(`feature${item.device_id}`, 0)
                this.cluster.source.removeFeature(feature)
            }

            feature.setVisibleOpen = (feature) => {
                const point = this.markerLayers.find(
                    (o) => o.data.device_id == item.device_id
                )

                if (point.layer.get(`feature${item.device_id}`)) {
                    return
                }

                if (point.layer.get(`feature${item.device_id}`) == 0) {
                    point.layer.set(`feature${item.device_id}`, 1)

                    if (this.cluster) {
                        this.cluster.source.addFeature(feature)
                    }
                }
            }

            feature.setNameClose = (feature) => {
                const newStyle = {
                    image: this.createMarkerIcon(item),
                    text: {}
                }
                var obj = objectMerge(
                    {
                        point: [],
                        style: newStyle
                    },
                    item
                )
                feature.setStyle(new Style(setStyle(obj.style)))
            }
            feature.setNameOpen = (feature) => {
                const newStyle = {
                    image: this.createMarkerIcon(item),
                    text: this.createMarkerText(item)
                }
                var obj = objectMerge(
                    {
                        point: [],
                        style: newStyle
                    },
                    item
                )
                feature.setStyle(new Style(setStyle(obj.style)))
            }

            feature.setStyle(new Style(setStyle(obj.style)))
            if (camera_types.includes(item.node_id)) {
                //是摄像需要添加照射
                // this.createSectorLayer(item)
            }
            this.markerLayers.push({
                feature: feature,
                data: item
            })
            source.addFeature(feature)

            this.moverLayersData[obj.marker_id] = feature
        })
        // 聚合
        this.cluster = new Cluster({
            source: source,
            distance: 50
        })

        // 创建图层
        let layer = new VectorLayer({
            zIndex: 200,
            source: this.cluster,
            style: function (feature, resolution) {
                let size = feature.get('features').length
                if (size == 1) {
                    return feature.values_.features[0].getStyle()
                }
                var VectorLayerText = new Text({
                    text: size.toString(),
                    font: '14px sans-serif',
                    textAlign: 'center', //位置
                    padding: [0, 0, 0, 0],
                    textBaseline: 'alphabetic', //基准线
                    fill: new Fill({
                        color: 'blue'
                    })
                })
                var clusterIcon = require('@/assets/jhpoint.png')
                return new Style({
                    image: new Icon({
                        src: clusterIcon
                    }),
                    text: VectorLayerText
                })
            }
        })
        this.markerLayers.forEach((item) => {
            item.layer = layer
        })
        //添加进map
        if (this.map !== null) {
            this.map.addLayer(layer)
        }
    }
    /**
     * @description: 创建扇形图层(摄像机添加照射角度)
     * @param {*} item
     * @returns
     */
    createSectorLayer(item) {
        const extend = item.extend
        if (!extend[0] || (!extend[1] && !extend[2])) {
            return
        }
        if (extend[0] * 1 == 0) {
            return
        }
        if (extend[1] * 1 == extend[2] * 1) {
            return
        }
        // 设置扇型参数
        const center = [item.x * 1, item.y * 1] // 扇型中心点 (经度, 纬度)
        const radius = extend[0] ? extend[0] * 1 : 200 // 扇型的半径 (单位: 度，具体值依据需求调整)
        const startAngle = extend[1] ? extend[1] * 1 : 0 // 扇型起始角度 (单位: 度)
        const endAngle = extend[2] ? extend[2] * 1 : 90 // 扇型结束角度 (单位: 度)
        // 创建扇型
        const fanGeometry = this.createFan(center, radius, startAngle, endAngle)

        // 创建一个图层来显示扇型
        const layer = new VectorLayer({
            source: new VectorSource({
                features: [new Feature(fanGeometry)]
            }),
            style: new Style({
                fill: new Fill({
                    color: 'rgba(255, 0, 0, 0.5)' // 填充颜色
                }),
                stroke: new Stroke({
                    color: '#ff0000', // 边界颜色
                    width: 2
                })
            }),
            visible: true
        })
        this.sectorLayers[item.device_id] = layer
        // 将扇型图层添加到地图
        this.map.addLayer(layer)
    }
    /**
     * 创建扇形函数
     * @param {*} center
     * @param {*} radius
     * @param {*} startAngle
     * @param {*} endAngle
     * @param {*} numPoints
     * @returns
     */
    createFan(center, radius, startAngle, endAngle, numPoints = 100) {
        let coordinates = [center] // 扇型的起点是中心点

        // 处理跨越0度的情况（如330度到30度）
        let angleRange = endAngle - startAngle
        if (angleRange < 0) {
            angleRange += 360 // 调整为正值，例如330到30度变为330到390度（即30+360）
        }

        let angleStep = angleRange / numPoints // 每个点之间的角度差
        //let angleStep = (endAngle - startAngle) / numPoints // 每个点之间的角度差

        // 计算扇型的边界点
        for (let i = 0; i <= numPoints; i++) {
            // 将输入角度转换为以水平左侧为0度的坐标系
            // 在这个坐标系中，0度是水平左侧，顺时针旋转
            let angle = startAngle + angleStep * i

            // 确保角度在0-360范围内
            if (angle >= 360) angle -= 360

            // 将角度转换为弧度，并调整为数学坐标系
            // 数学坐标系中，0度是水平右侧，逆时针旋转
            // 所以需要加180度并取反
            let radian = (((180 + angle) * Math.PI) / 180) * -1

            // 计算边界点的经纬度
            let x = center[0] + radius * Math.cos(radian)
            let y = center[1] + radius * Math.sin(radian)

            coordinates.push([x, y])
        }

        // 返回一个 Polygon 对象
        return new Polygon([coordinates])
    }
    /***
     * 创建网格的方法
     */
    createPolygon(data) {
        data.forEach((element) => {
            const vectorSource = new VectorSource()
            const feature = new Feature({
                geometry: new Polygon([element.extend]),
                data: element
            })
            feature.setId(element.id)
            vectorSource.addFeature(feature)
            const layer = new VectorLayer({
                source: vectorSource,
                style: (feature) => {
                    return new Style({
                        stroke: new Stroke({
                            color: 'blue',
                            width: 3
                        }),
                        fill: new Fill({
                            color: 'rgba(0, 0, 255, 0.1)'
                        }),
                        text: new Text({
                            text: feature.get('data').name, // 取 feature 里的 data.name
                            textAlign: 'center',
                            font: '14px sans-serif', // 修正字体格式
                            fill: new Fill({
                                color: '#fff'
                            })
                        })
                    })
                }
            })
            // 获取多边形的外包围矩形（extent）
            const extent = feature.getGeometry().getExtent()
            // 计算中心点
            const center = getCenter(extent)
            layer.set('id', element.id)
            layer.set('name', element.name)
            layer.set('center', center)
            this.map.addLayer(layer)
            this.Polygonadd.push(layer)
        })
    }
    /**
     * 单个网格设置样式
     * @param {*} val
     */
    setstylePolyon(val) {
        if (this.features) {
            this.features.setStyle(
                new Style({
                    //填充色
                    fill: new Fill({
                        color: val.ccolor
                    }),
                    //边线颜色
                    stroke: new Stroke({
                        color: val.bcolor,
                        width: val.num
                    }),
                    text: new Text({
                        // 位置
                        textAlign: val.textalinen,
                        // 基准线
                        textBaseline: 'middle',
                        // 文字样式
                        font: 'bold ' + val.size + 'px ' + val.family,
                        // 文本内容
                        text: val.text,
                        // 文字颜色
                        fill: new Fill({ color: val.color }),
                        // 文字背景
                        stroke: new Stroke({ color: '#353535', width: 1 })
                    })
                })
            )
        }
    }
    /**
     * 清除网格的方法
     * @param {*} item
     */
    removePolygon(item) {
        // new Polygon
        this.Polygonadd.forEach((element) => {
            this.map.removeLayer(element)
        })
    }
    /**
     * 清除拖动标线的方法
     */
    removeLine() {
        this.lineLayers.forEach((element) => {
            this.map.removeLayer(element)
        })
    }
    /**
     * 需要传递给openlayers.vue的方法
     * 实现和openlayers.vue  进行数据交互
     * 1:点击点位  clickMarker
     * 2:点击网格  clickGird
     * 3:网格绘制完成的事件 gridModifyEnd
     */
    clickMap(e) {}

    clickMarker(e) {}

    clickGird(e) {}
    clickLineFeatures(e) {}
    gridModifyEnd(e) {}

    // addInteractions() {
    //     var draw = new Draw({
    //         source: new VectorSource({
    //             features: [this.features]
    //         }),
    //         type: 'LineString'
    //     })
    //     this.map.addInteraction(draw)
    //     var snap = new Snap({ source: source })
    //     this.map.addInteraction(snap)
    // }
    /**
     * 关闭报警红框
     * @param {*} val
     * @returns
     */

    closePopup(val) {
        if (!val || typeof val.device_id === 'undefined') {
            return
        }
        const deviceId = String(val.device_id)
        const currentPoint = this.markerLayers.find(
            (item) => item.data.device_id === val.device_id
        )
        if (!currentPoint || !this.deviceAlarmNum[deviceId]) {
            return
        }
        const markerKey = `device${deviceId}`
        if (this.markerOrCluster[markerKey]) {
            if (this.deviceAlarmNum[deviceId] > 1) {
                this.deviceAlarmNum[deviceId] -= 1
                return
            }
            this.map.removeOverlay(this.allPopupList[deviceId])
            delete this.allPopupList[deviceId]
            delete this.deviceAlarmNum[deviceId]
        } else {
            for (let i = 0; i < this.alarmClusterArr.length; i++) {
                const clusterPoint = this.alarmClusterArr[i]
                if (!clusterPoint[deviceId]) {
                    continue
                }
                if (this.deviceAlarmNum[deviceId] > 1) {
                    this.deviceAlarmNum[deviceId] -= 1
                } else {
                    delete this.deviceAlarmNum[deviceId]
                }
                if (clusterPoint[0][2] <= 1) {
                    const indexKey = `index${i}`
                    this.map.removeOverlay(this.allPopupList[indexKey])
                    delete this.allPopupList[indexKey]
                    this.alarmClusterArr[i][0][2] = 0
                } else {
                    this.alarmClusterArr[i][0][2] -= 1
                }
            }
        }
        console.log('closePopup', this.deviceAlarmNum)
    }

    test(list, e) {
        this.deviceAlarmNum = list

        if (e?.device_id) {
            const deviceId = String(e.device_id)
            this.deviceAlarmNum[deviceId] =
                (this.deviceAlarmNum[deviceId] || 0) + 1

            const currentPoint = this.markerLayers.find(
                (item) => item.data.device_id === e.device_id
            )

            currentPoint?.feature?.setVisibleOpen(currentPoint.feature)
        }

        if (!this.cluster) return

        this.markerOrCluster = []
        this.alarmClusterArr = []

        const markersData = this.cluster.features
        markersData.forEach((item) => {
            const features = item.values_.features

            if (features.length === 1) {
                // Handle single marker
                const feature = features[0].values_.data
                const deviceId = `device${feature.device_id}`
                this.markerOrCluster[deviceId] = [feature.x, feature.y]
            } else {
                // Handle cluster
                const clusterCoords = item.values_.geometry.flatCoordinates
                const clusterArr = [
                    [clusterCoords[0], clusterCoords[1], 0] // Initialize alarm count as 0
                ]

                features.forEach((feature) => {
                    const deviceId = feature.values_.data.device_id
                    clusterArr[deviceId] = []
                    clusterArr[0][2] +=
                        this.deviceAlarmNum[String(deviceId)] || 0
                })

                this.alarmClusterArr.push(clusterArr)
            }
        })

        this.addPopup()
    }

    dataTransform(obj) {
        let key = Object.keys(obj)
        let val = Object.values(obj)
        let data = key.map((item, index) => {
            return {
                name: val[index],
                id: item
            }
        })
        return data
    }

    /**
     * @description: 关闭报警弹窗
     */
    closeAlarmPopup() {
        // 获取所有覆盖物
        const overlays = this.map.getOverlays().getArray()
        // 遍历所有覆盖物，找到并删除带有特定自定义属性的覆盖物
        overlays.forEach((overlay) => {
            // 使用get方法获取自定义属性
            if (overlay.get('label') === 'alarm') {
                this.map.removeOverlay(overlay)
            }
        })
    }
    // 添加红色报警框
    addPopup() {
        // 清除现有的覆盖物
        // this.map.getOverlays().clear()
        this.closeAlarmPopup()
        // 获取警告元素模板
        const warningTemplate = document.getElementsByClassName('warning')[0]
        if (!warningTemplate) {
            console.warn('Warning element template not found')
            return
        }

        // 记录已处理的聚合点
        const processedClusters = new Set()

        // 处理设备报警
        Object.entries(this.deviceAlarmNum).forEach(([index]) => {
            // 创建弹窗元素
            const popupElement = warningTemplate.cloneNode()
            popupElement.style.display = 'block'

            // 创建覆盖物
            const popup = new Overlay({
                element: popupElement,
                position: [],
                offset: [-18, -18],
                className: 'ol-popup-info',
                stopEvent: false
            })
            popup.set('label', 'alarm')
            const deviceKey = `device${index}`

            // 处理单个设备标记
            if (this.markerOrCluster[deviceKey]) {
                popup.setPosition(this.markerOrCluster[deviceKey])
                this.map.addOverlay(popup)
                this.allPopupList[index] = popup
                return
            }

            // 处理聚合点
            this.alarmClusterArr.forEach((cluster, i) => {
                if (processedClusters.has(i) || !cluster[index]) return

                processedClusters.add(i)
                popup.setPosition([cluster[0][0], cluster[0][1]])
                this.map.addOverlay(popup)
                this.allPopupList[`index${i}`] = popup
            })
        })
    }

    createMarkers1(item, condition) {
        let coordinates = [item.x, item.y]
        let feature1 = new Feature({
            geometry: new Point(coordinates),
            data: item
        })
        let srcjhpoint = require('@/assets/jhpoint.png')

        var startStyle = new Style({
            image: new Icon({
                scale: 0.5,
                src: srcjhpoint,
                // src: 'http://192.168.0.90:8040/marker/1/1/1.png',
                // src: 'http://192.168.0.109:9601/assets/jhpoint.png',
                size: [40, 40]
            })
        })
        this.markerLayer = new layersVector({
            zIndex: 200,
            source: new VectorSource({
                features: [feature1]
            }),
            style: startStyle
        })
        this.map.addLayer(this.markerLayer)

        this.markerLayers = [
            {
                feature: feature1,
                data: item
            }
        ]
    }

    createcircleLayer1(item, SHOW) {
        if (SHOW == 1) {
            var circle = new Circle([item.x, item.y], item.range) // 新建圆对象
            var startStyle = new Style({
                stroke: new Stroke({
                    color: item.extend.bcolor,
                    width: item.extend.num
                }),
                fill: new Fill({
                    color: item.extend.ccolor
                })
            })
            var feature = new Feature(circle)
            // 新建Feature对象 并将circle传入
            var circleLayer = new VectorLayer({
                // 源于"ol/layer"
                zIndex: 100,
                visible: true,
                // softMove()内的时间容器
                source: new VectorSource({
                    features: [feature]
                }),
                style: startStyle
            })
            if (this.Layer) {
                this.Layer.setVisible(true)
            } else {
                this.Layer = circleLayer
                this.map.addLayer(this.Layer) // 将图层添至地图对象
            }
        } else if (this.Layer) {
            this.Layer.setVisible(false)
        }
    }

    createcircleLayer2(item, SHOW) {
        this.map.removeLayer(this.Layer)
        if (SHOW == 1) {
            var circle = new Circle([item.x, item.y], item.range) // 新建圆对象
            var startStyle = new Style({
                stroke: new Stroke({
                    color: item.extend.bcolor,
                    width: item.extend.num
                }),
                fill: new Fill({
                    color: item.extend.ccolor
                })
            })
            var feature = new Feature(circle)
            // 新建Feature对象 并将circle传入
            var circleLayer = new VectorLayer({
                // 源于"ol/layer"
                zIndex: 100,
                visible: true,
                // softMove()内的时间容器
                source: new VectorSource({
                    features: [feature]
                }),
                style: startStyle
            })
            this.Layer = circleLayer
            this.map.addLayer(this.Layer) // 将图层添至地图对象
        }
    }

    createCircleLayerList(list) {
        // console.log(list)
        // item, SHOW
        list.forEach((item) => {
            if (item.is_open == 1 && item.extend) {
                var circle = new Circle([item.x, item.y], item.range) // 新建圆对象
                var startStyle = new Style({
                    stroke: new Stroke({
                        color: (item.extend && item.extend.bcolor) || '',
                        width: item.extend && item.extend.num
                    }),
                    fill: new Fill({
                        color: item.extend && item.extend.ccolor
                    })
                })
                var feature = new Feature(circle)
                // 新建Feature对象 并将circle传入
                var circleLayer = new VectorLayer({
                    // 源于"ol/layer"
                    zIndex: 100,
                    visible: true,
                    // softMove()内的时间容器
                    source: new VectorSource({
                        features: [feature]
                    }),
                    style: startStyle,
                    data: item
                })

                this.map.addLayer(circleLayer)
                this.circleArr.push(circleLayer)
            }
        })
    }

    setapplyTransform() {
        // 创建一个变换函数
        const transformFn = (pixel) => {
            // 对每个像素的坐标进行变换
            const newCoordinates = {}
            return newCoordinates
        }
        const newCoordinates = {}
        // 使用 applyTransform 方法对地图上的每个像素进行变换
        map.applyTransform(transformFn)
    }

    // 修改点位样式(设备状态改变图标)
    setMarkerIcon(row) {
        const layer = this.markerLayers.find(
            (item) => item.data.device_id == row.device_id
        )
        if (!layer) return
        const text = new Text({
            textAlign: 'center', //位置
            padding: [5, 8, 5, 8],
            textBaseline: 'middle', //基准线
            font: 'bold 12px 微软雅黑', //'normal 12px 微软雅黑', //文字样式
            text: row.device_name || row.name || '', //文本内容
            offsetY: -22,
            fill: new Fill({
                color: row.color || '#2564fc'
            })
        })
        const style = new Style({
            image: new Icon(this.createMarkerIcon(row)),
            text: text
        })
        layer.feature.setStyle(style)
    }
    /**
     * @description 打开车辆通行弹窗
     * @param {*} e
     * @returns
     */
    openCarModal(e) {
        const position = this.markerOrCluster[`device${e.device_id}`]
        if (!position) return
        // 创建弹窗元素
        const element = document.createElement('div')
        element.style.width = '400px'
        element.style.height = '220px'
        element.style.background = 'white'
        element.style.border = '1px solid black'

        // 创建二级标签
        const subDiv1 = document.createElement('div')
        subDiv1.style.height = '40px'
        subDiv1.style.borderBottom = '1px solid black'
        subDiv1.style.display = 'flex'
        subDiv1.style.flexDirection = 'row'
        subDiv1.style.justifyContent = 'space-between'
        subDiv1.style.alignItems = 'center'
        subDiv1.style.padding = '0 10px'

        const subDiv11 = document.createElement('div')
        subDiv11.style.color = '#000'
        subDiv11.innerHTML = `<strong>${e.device_name}</strong>`
        subDiv1.appendChild(subDiv11)

        const subDiv12 = document.createElement('img')
        subDiv12.style.width = '25px'
        subDiv12.style.height = '25px'
        subDiv12.style.cursor = 'pointer'
        subDiv12.src = require('@/assets/close.png')
        // 添加点击事件关闭当前Overlay
        subDiv12.addEventListener('click', () => {
            // 获取所有覆盖物
            const overlays = this.map.getOverlays().getArray()
            // 遍历所有覆盖物，找到并删除当前的覆盖物
            overlays.forEach((overlay) => {
                if (overlay.getElement() === element) {
                    this.map.removeOverlay(overlay)
                }
            })
        })
        subDiv1.appendChild(subDiv12)
        // 创建三级标签
        const subDiv2 = document.createElement('div')
        subDiv2.style.padding = '10px'
        subDiv2.style.display = 'flex'
        subDiv2.style.flexDirection = 'row'
        subDiv2.style.justifyContent = 'flxt-start'

        const subDiv21 = document.createElement('img')
        subDiv21.style.width = '150px'
        subDiv21.style.height = '150px'

        let image
        if (e.images) {
            image =
                e.images.image ||
                e.images.scene ||
                require('@/assets/no-image.png')
        }
        subDiv21.src = `${image}`
        subDiv2.appendChild(subDiv21)

        const subDiv22 = document.createElement('div')
        subDiv22.style.flex = 1
        subDiv22.style.paddingLeft = '10px'
        subDiv22.style.display = 'flex'
        subDiv22.style.flexDirection = 'column'
        subDiv2.appendChild(subDiv22)

        const subDiv221 = document.createElement('div')
        subDiv221.style.height = '28px'
        subDiv221.style.lineHeight = '28px'
        subDiv221.style.fontSize = '14px'
        subDiv221.innerHTML = `车牌号码:${e.car_no}`
        subDiv22.appendChild(subDiv221)

        const subDiv222 = document.createElement('div')
        subDiv222.style.height = '28px'
        subDiv222.style.lineHeight = '28px'
        subDiv222.style.fontSize = '14px'
        subDiv222.innerHTML = `行驶速度:${e.speed}`
        subDiv22.appendChild(subDiv222)

        const subDiv223 = document.createElement('div')
        subDiv223.style.height = '28px'
        subDiv223.style.lineHeight = '28px'
        subDiv223.style.fontSize = '14px'
        subDiv223.innerHTML = `车辆类型:${e.car_type}`
        subDiv22.appendChild(subDiv223)

        const subDiv224 = document.createElement('div')
        subDiv224.style.height = '28px'
        subDiv224.style.lineHeight = '28px'
        subDiv224.style.fontSize = '14px'
        subDiv224.innerHTML = `车辆颜色:${e.car_color}`
        subDiv22.appendChild(subDiv224)

        const subDiv225 = document.createElement('div')
        subDiv225.style.height = '28px'
        subDiv225.style.lineHeight = '28px'
        subDiv225.style.fontSize = '14px'
        subDiv225.innerHTML = `通行时间:${e.create_time}`
        subDiv22.appendChild(subDiv225)
        // 将子元素附加到主div
        element.appendChild(subDiv1)
        element.appendChild(subDiv2)

        // 创建覆盖物
        const popup = new Overlay({
            element: element,
            position: [],
            offset: [-210, -240],
            className: 'ol-popup-info',
            stopEvent: false,
            properties: {
                label: 'car'
            }
        })
        popup.setPosition(position)
        this.map.addOverlay(popup)
    }
    /**
     * @description: 通行记录地图展示通行信息
     * @param {*} e
     * @returns
     */
    openAccessModal(e) {
        const position = this.markerOrCluster[`device${e.device_id}`]
        if (!position) return

        const overlay = this.accessOverlay[e.device_id] || null
        if (overlay) {
            this.map.removeOverlay(overlay)
        }
        // 创建弹窗元素
        const element = document.createElement('div')
        element.style.width = '400px'
        element.style.height = '220px'
        element.style.background = 'white'
        element.style.border = '1px solid black'

        // 创建二级标签
        const subDiv1 = document.createElement('div')
        subDiv1.style.height = '40px'
        subDiv1.style.borderBottom = '1px solid black'
        subDiv1.style.display = 'flex'
        subDiv1.style.flexDirection = 'row'
        subDiv1.style.justifyContent = 'space-between'
        subDiv1.style.alignItems = 'center'
        subDiv1.style.padding = '0 10px'

        const subDiv11 = document.createElement('div')
        subDiv11.style.color = '#000'
        subDiv11.innerHTML = `<strong>${e.device_name}</strong>`
        subDiv1.appendChild(subDiv11)

        const subDiv12 = document.createElement('img')
        subDiv12.style.width = '25px'
        subDiv12.style.height = '25px'
        subDiv12.style.cursor = 'pointer'
        subDiv12.src = require('@/assets/close.png')
        // 添加点击事件关闭当前Overlay
        subDiv12.addEventListener('click', () => {
            // 获取所有覆盖物
            const overlays = this.map.getOverlays().getArray()
            // 遍历所有覆盖物，找到并删除当前的覆盖物
            overlays.forEach((overlay) => {
                if (overlay.getElement() === element) {
                    this.map.removeOverlay(overlay)
                }
            })
        })
        subDiv1.appendChild(subDiv12)
        // 创建三级标签
        const subDiv2 = document.createElement('div')
        subDiv2.style.padding = '10px'
        subDiv2.style.display = 'flex'
        subDiv2.style.flexDirection = 'row'
        subDiv2.style.justifyContent = 'flxt-start'

        const subDiv21 = document.createElement('img')
        subDiv21.style.width = '150px'
        subDiv21.style.height = '150px'
        if (e.avatar) {
            subDiv21.src = `${e.avatar}`
        } else {
            subDiv21.src = require('@/assets/header/avatar.png')
        }
        subDiv2.appendChild(subDiv21)

        const subDiv22 = document.createElement('div')
        subDiv22.style.flex = 1
        subDiv22.style.paddingLeft = '10px'
        subDiv22.style.display = 'flex'
        subDiv22.style.flexDirection = 'column'
        subDiv2.appendChild(subDiv22)

        const subDiv221 = document.createElement('div')
        subDiv221.style.height = '28px'
        subDiv221.style.lineHeight = '28px'
        subDiv221.style.fontSize = '14px'
        subDiv221.innerHTML = `人员姓名:${e.user_name}`
        subDiv22.appendChild(subDiv221)

        const subDiv222 = document.createElement('div')
        subDiv222.style.height = '28px'
        subDiv222.style.lineHeight = '28px'
        subDiv222.style.fontSize = '14px'
        subDiv222.innerHTML = `证件号码:${e.id_number}`
        subDiv22.appendChild(subDiv222)

        const subDiv223 = document.createElement('div')
        subDiv223.style.height = '28px'
        subDiv223.style.lineHeight = '28px'
        subDiv223.style.fontSize = '14px'
        subDiv223.innerHTML = `人员卡号:${e.card_no}`
        subDiv22.appendChild(subDiv223)

        // const subDiv224 = document.createElement('div')
        // subDiv224.style.height = '28px'
        // subDiv224.style.lineHeight = '28px'
        // subDiv224.style.fontSize = '14px'
        // subDiv224.innerHTML = `设备名称:${e.device_name}`
        // subDiv22.appendChild(subDiv224)

        const subDiv225 = document.createElement('div')
        subDiv225.style.height = '28px'
        subDiv225.style.lineHeight = '28px'
        subDiv225.style.fontSize = '14px'
        subDiv225.innerHTML = `出入方向:${e.inout_name}`
        subDiv22.appendChild(subDiv225)
        // 将子元素附加到主div
        element.appendChild(subDiv1)
        element.appendChild(subDiv2)

        // 创建覆盖物
        const popup = new Overlay({
            element: element,
            position: [],
            offset: [-210, -240],
            className: 'ol-popup-info',
            stopEvent: false,
            properties: {
                label: 'access'
            }
        })
        this.accessOverlay[e.device_id] = popup
        popup.setPosition(position)
        this.map.addOverlay(popup)
    }

    createMarkers(markers) {
        // let source = new VectorSource()
        markers.forEach((item, index) => {
            let coordinates = [item.x, item.y]
            let feature = new Feature({
                geometry: new Point(coordinates),
                data: item
            })
            var startStyle = new Style({
                image: new Icon({
                    anchor: [0.5, 0.5],
                    scale: 1,
                    src: item.icon,
                    size: [38, 52]
                }),
                text: new Text({
                    text: item.device_name,
                    // font: '14px font-size',
                    padding: [0, 0, 0, 0],
                    fill: new Fill({ color: '#fff' }),
                    backgroundFill: new Fill({ color: '#3737379e' }),
                    offsetY: 30
                })
            })
            let markerLayer = new layersVector({
                source: new Vector({
                    features: [feature]
                }),
                style: startStyle
            })
            this.map.addLayer(markerLayer)
        })
    }

    /**
     * 人员定位创建基础点位
     * @param {*} markers
     */
    initTrackMarker(markers) {
        // 复用已有的图层，避免重复创建
        if (!this.markerLayer) {
            this.markerLayer = new layersVector({
                source: new VectorSource()
            })
            this.map.addLayer(this.markerLayer)
        }
        // 获取图层的 source
        let source = this.markerLayer.getSource()
        // 清空旧的点位，避免重复渲染
        source.clear()
        markers.forEach((item) => {
            let coordinates = [item.x * 1, item.y * 1]
            let feature = new Feature({
                geometry: new Point(coordinates),
                data: item
            })
            // 设置点的样式
            feature.setStyle(
                new Style({
                    image: new StyleCircle({
                        radius: 5, // 圆形半径
                        fill: new Fill({ color: 'red' }), // 填充颜色
                        stroke: new Stroke({ color: '#ffd11a', width: 2 }) // 边框
                    })
                })
            )
            // 添加到 source（不会重复创建多个图层）
            source.addFeature(feature)
        })
    }
    /**
     * 添加人员定位初始点位
     * @param {*} msg
     */
    addPositionLayer(msg) {
        if (!this.map) {
            return
        }
        // 复用已有的图层，避免重复创建
        if (!this.markerLayer) {
            this.markerLayer = new layersVector({
                source: new VectorSource()
            })
            this.map.addLayer(this.markerLayer)
        }
        // 获取图层的 source
        let source = this.markerLayer.getSource()
        // 清空旧的点位，避免重复渲染
        // source.clear()
        let coordinates = [msg.x * 1, msg.y * 1]
        let feature = new Feature({
            geometry: new Point(coordinates),
            data: msg
        })
        // 设置点的样式
        feature.setStyle(
            new Style({
                image: new StyleCircle({
                    radius: 5, // 圆形半径
                    fill: new Fill({ color: 'red' }), // 填充颜色
                    stroke: new Stroke({ color: '#ffd11a', width: 2 }) // 边框
                }),
                text: new Text({
                    text: msg.username,
                    padding: [0, 0, 0, 0],
                    fill: new Fill({ color: '#fff' }),
                    backgroundFill: new Fill({ color: '#3737379e' }),
                    offsetY: -8
                })
            })
        )
        // 添加到 source（不会重复创建多个图层）
        source.addFeature(feature)
    }
    /**
     * 更新位置
     * @param {*} msg
     */
    updatePositionLayer(msg) {
        if (!this.markerLayer) {
            console.error('Marker 图层未初始化')
            return
        }
        let source = this.markerLayer.getSource()
        let features = source.getFeatures()
        // 查找对应的 Feature
        let feature = features.find(
            (f) => f.get('data').person_id === msg.person_id
        ) // 假设你的点位数据有 id 字段
        if (feature) {
            let coordinates = [msg.x * 1, msg.y * 1] // 确保是数值
            feature.setGeometry(new Point(coordinates)) // 更新位置
        } else {
            console.warn(`未找到 ID 为 ${msg.person_id} 的点位`)
        }
    }
    /**
     * 开启编辑点位
     * @param {callback} removeEnd 移动结束
     */
    editMarkers(removeEnd, removeStare) {
        const modify = new ExampleModify(
            this.map,
            this.markerLayers,
            removeEnd,
            removeStare
        )

        modify.start()
        this.modify_marker = true
        return modify
    }

    /**
     * 添加绘制功能
     * @param {Circle|LineString|Point||Square|MultiPolygon|MultiPoint|MultiLineString|Clear} type 绘制类型
     * @param {callback} setLine 设置坐标轴开关
     * @param {callback} onmousemove 设置鼠标移动回调
     */
    // addInteraction(type, style, setLine, onmousemove) {
    //     let source = new VectorSource()
    //     //实例化交互绘制类对象并添加到地图容器中
    //     const draw = new Draw({
    //         //绘制层数据源
    //         source: source,
    //         type: type
    //     })
    //     this.map.addInteraction(draw)
    //     //默认样式
    //     var styles = []
    //     if (style instanceof Array && style.length > 0) {
    //         styles = [
    //             new Style({
    //                 stroke: new Stroke({
    //                     color: style[0].bcolor,
    //                     width: style[0].num
    //                 }),
    //                 fill: new Fill({
    //                     color: style[0].ccolor
    //                 }),
    //                 text: new Text({
    //                     text: style[0].text,
    //                     textAlign: style[0].textaline,
    //                     font: style[0].size,
    //                     padding: [4, 7, 4, 7],
    //                     fill: new Fill({ color: style[0].color }),
    //                     // backgroundFill: new Fill({ color: '#3737379e' }),
    //                     offsetY: 30
    //                 })
    //             })
    //         ]
    //     } else {
    //         styles = [
    //             new Style({
    //                 stroke: new Stroke({
    //                     color: 'rgba(197, 232, 18, 1)',
    //                     width: 3
    //                 }),
    //                 fill: new Fill({
    //                     color: 'rgba(221, 69, 69, 0.91))'
    //                 }),
    //                 text: new Text({
    //                     text: style[0].text,
    //                     // font: '14px font-size',
    //                     padding: [4, 7, 4, 7],
    //                     fill: new Fill({ color: '#fff' }),
    //                     backgroundFill: new Fill({ color: '#3737379e' }),
    //                     offsetY: 30
    //                 })
    //             })
    //         ]
    //     }
    //     //画一条横线
    //     const lineObj = new Feature({
    //         geometry: new LineString([
    //             [0, 0],
    //             [70, 70],
    //         ])
    //     });

    //     //实例化一个矢量图层Vector作为绘制层
    //     var source1 = new VectorSource({
    //         features: [lineObj]
    //     });
    //     //创建一个图层
    //     var vector11 = new VectorLayer({
    //         source: source1
    //     });

    //     //画一条竖线
    //     const verticalLine = new Feature({
    //         geometry: new LineString([
    //             [0, 0],
    //             [70, 70],
    //         ])
    //     });

    //     //实例化一个矢量图层Vector作为绘制层
    //     var verticalLineSource = new VectorSource({
    //         features: [verticalLine]
    //     });
    //     //创建一个图层
    //     var verticalLineVector = new VectorLayer({
    //         source: verticalLineSource
    //     });
    //     //将绘制层添加到地图容器中
    //     /**
    //      * 结束绘制函数
    //      * @param {callback} end
    //      */
    //     let end = () => { }
    //     /**
    //      * 初始化绘制时的结束方法
    //      */
    //     draw.on('drawend', ({ feature, target }) => {
    //         console.log('feature', { feature })
    //         feature.set('grid_index', style[0].grid_index)
    //         this.gridModifyEnd({ feature })
    //         source = new VectorSource({
    //             features: [feature]
    //         })
    //         const layer = new VectorLayer({
    //             source: source,
    //             style: styles,
    //             visible: true
    //         })
    //         this.map.addLayer(layer)
    //         this.Polygonadd.push(layer)
    //         this.contetnList.push({
    //             list: feature.getGeometry().getCoordinates()
    //         })
    //         this.map.removeInteraction(draw)

    //         let modify = new Modify({
    //             features: new Collection([feature]),
    //             pixelTolerance: 5,
    //             style: [
    //                 new Style({
    //                     stroke: new Stroke({
    //                         color: 'yellow',
    //                         width: 3
    //                     }),
    //                     fill: new Fill({
    //                         color: 'yellow'
    //                     }),
    //                     text: new Text({
    //                         text: style[0].text,
    //                         // font: '14px font-size',
    //                         padding: [4, 7, 4, 7],
    //                         fill: new Fill({ color: '#fff' }),
    //                         backgroundFill: new Fill({ color: '#3737379e' }),
    //                         offsetY: 30
    //                     })
    //                 })
    //             ]
    //         })

    //         // const Line = new Feature({
    //         //     geometry: new LineString([
    //         //         [0, 0],
    //         //         [70, 70],
    //         //     ])
    //         // });

    //         // //实例化一个矢量图层Vector作为绘制层
    //         // var source1 = new VectorSource({
    //         //     features: [Line]
    //         // });
    //         // //创建一个图层
    //         // var vector11 = new VectorLayer({
    //         //     source: source1
    //         // });
    //         // this.map.addLayer(vector11)

    //         let startMove = false
    //         this.map.on('pointermove', ({ pixel }) => {
    //             console.log('pointermove')
    //             if (startMove) {
    //                 console.log(pixel);

    //                 onmousemove(pixel)
    //             }
    //             // let coordinates = features.getGeometry().getCoordinates()
    //             // this.girdContent = coordinates[0]
    //             var condition = this.map.getCoordinateFromPixel(pixel)
    //             lineObj.setGeometry(
    //                 new LineString([
    //                     [0, condition[1]],
    //                     [1200, condition[1]]
    //                 ])
    //             )
    //             lineObj.setStyle(new Style({
    //                 //边线颜色
    //                 stroke: new Stroke({
    //                     color: '#3333ff',
    //                     width: 1
    //                 })
    //             }))
    //             verticalLine.setGeometry(
    //                 new LineString([
    //                     [condition[0], 0],
    //                     [condition[0], 800]
    //                 ])
    //             )
    //             verticalLine.setStyle(new Style({
    //                 //边线颜色
    //                 stroke: new Stroke({
    //                     color: '#3333ff',
    //                     width: 1
    //                 })
    //             }))
    //             this.girdContent.forEach(item => {
    //                 // console.log('item', item[0])
    //                 // console.log('condition', condition[0])
    //                 if (item[0] == condition[0]) {
    //                     // var y = condition[1] + (item[1] - condition[1]) / 2
    //                     console.log('垂直对齐')
    //                     verticalLine.setStyle(new Style({
    //                         //边线颜色
    //                         stroke: new Stroke({
    //                             color: '#ff0000',
    //                             width: 3
    //                         })
    //                     }))
    //                 }
    //                 if (item[1] == condition[1]) {
    //                     // var y = condition[1] + (item[1] - condition[1]) / 2
    //                     console.log('垂直对齐')
    //                     lineObj.setStyle(new Style({
    //                         //边线颜色
    //                         stroke: new Stroke({
    //                             color: '#ff0000',
    //                             width: 3
    //                         })
    //                     }))
    //                 }
    //             })
    //         })
    //         this.map.on('pointerend', ({ pixel }) => {
    //             // if (startMove) {
    //             //     onmousemove(pixel);
    //             // }
    //         })
    //         modify.on('modifystart', evt => {
    //             var feature = evt.features.array_[0]
    //             let featureObj = { feature }
    //             let coordinates = featureObj.feature.getGeometry().getCoordinates()
    //             this.girdContent = coordinates[0]

    //             this.map.addLayer(verticalLineVector)
    //             this.map.addLayer(vector11)
    //             startMove = true
    //             setLine(true)
    //         })

    //         modify.on('modifyend', e => {
    //             var feature = e.features.array_[0]
    //             console.log(feature);
    //             this.map.removeLayer(verticalLineVector)
    //             this.map.removeLayer(vector11)
    //             this.gridModifyEnd({ feature })

    //             startMove = false
    //             setLine(false)
    //         })

    //         this.map.addInteraction(modify)
    //         //设置结束事件
    //         end = () => {
    //             this.map.removeInteraction(modify)
    //         }
    //     })
    //     return end
    // }

    addPolygon(item) {
        // new Polygon
        this.Polygonadd.forEach((element) => {
            this.map.addLayer(element)
        })
    }

    removePolygonByType() {
        this.Polygonadd.forEach((element) => {
            this.map.removeLayer(element)
        })
    }

    addPolygonByType(item) {
        // console.log(item)
        nextTick(() => {
            this.map.addLayer(item)
        })
    }

    removeMap() {
        this.map = null
    }

    /**
     * 打开右键菜单
     */
    initContentMenu(options) {
        let contentmenu = new ContentMenu(document.getElementById(options.id), {
            items: []
        })
        contentmenu.init()
        this.map.getViewport().oncontextmenu = (e) => {
            if (this.isDraw) {
                return
            }
            e.preventDefault()
            let pixel = this.map.getEventPixel(e)
            let features = this.map.forEachFeatureAtPixel(pixel, (feature) => {
                //根据像素坐标获取右键选中的地图要素
                return feature
            })
            if (!features) return

            const geometry = features.getGeometry()
            const geometryType = geometry.getType()
            let opt = [] // 右键菜单选项
            let data = {} // 要素数据
            let i = -1 // 要素索引

            // // 获取要素的基本数据
            // if (features.values_.data) {
            //     data = features.values_.data
            // }
            switch (geometryType) {
                case 'Polygon':
                    opt = options.polygon
                    data = features.values_.data
                    break
                case 'Point':
                    data = features.values_.features[0].values_.data
                    for (let i in options.point) {
                        if (data.is_alarm && options.point[i].id == 4) {
                            opt.push(options.point[i])
                        } else if (!data.is_alarm && options.point[i].id == 4) {
                        } else {
                            opt.push(options.point[i])
                        }
                    }
                    i = this.markerLayers.findIndex(
                        (o) => o.feature.getId() == features.getId()
                    )
                    break
                case 'LineString':
                case 'MultiLineString':
                    // 获取线的菜单选项
                    opt = options.line
                    data = features.values_
                    break
            }
            //设置菜单选项并打开菜单
            contentmenu.setMenuOptions({ items: opt })
            const obj = {
                feature_: features,
                geom_: geometry,
                data_: data,
                layer_: this.markerLayers[i]?.layer || this.lineLyers[i]?.layer,
                index_: i
            }
            contentmenu.open(pixel, obj)
        }

        this.map.getViewport().onmousedown = (e) => {
            if (e.which != 3) {
                contentmenu.close()
            }
        }
    }

    /**
     * 获取地图中心点坐标
     * @returns {array}
     */
    getMapCenter() {
        var mapExtent = this.map.getView().calculateExtent(this.map.getSize())
        var mapExtent1 = getCenter(mapExtent)
        return mapExtent1
    }

    getMarkerCenter() {
        return this.markerCenter
    }

    clearMarkerCenter() {
        this.markerCenter = []
    }
}

function objectMerge(obj1, obj2) {
    let key
    for (key in obj2) {
        // 如果target(也就是obj1[key])存在，且是对象的话再去调用deepMerge，否则就是obj1[key]里面没这个对象，需要与obj2[key]合并
        obj1[key] =
            obj1[key] && obj1[key].toString() === '[object Object]'
                ? objectMerge(obj1[key], obj2[key])
                : (obj1[key] = obj2[key])
    }
    return obj1
}

/**
 * 右键菜单
 */
class ContentMenu {
    show_ = false

    menu_ = null

    object_ = {}

    /**
     *
     * @param {HTMLElement} target
     * @param {Object} opt_options
     */
    constructor(target, opt_options) {
        this.options_ = opt_options || {}
        this.target = target
    }

    init() {
        let now = document.getElementById('ol-contentmenu')
        if (now) {
            this.target.removeChild(now)
        }
        this.menu_ = document.createElement('div')
        this.menu_.id = 'ol-contentmenu'
        this.menu_.className = 'ol-contentmenu'
        this.menu_.style.visibility = 'hidden'

        if (typeof this.options_.items == 'object') {
            const ul = document.createElement('ul')
            ul.className = 'ol-contentmenu-ul'
            this.menu_.appendChild(ul)

            for (let i in this.options_.items) {
                const li = document.createElement('li')
                li.className = 'ol-contentmenu-item'
                li.innerText = this.options_.items[i].text
                li.style.padding = '3px 5px'
                li.onclick = (e) => {
                    this.close()
                    this.options_.items[i].callback({
                        target: e,
                        ...this.object_
                    })
                }
                ul.appendChild(li)
            }
        }
        this.target.appendChild(this.menu_)
    }

    setMenuOptions(opt_options) {
        this.options_ = opt_options || {}
        this.init()
    }

    addItem(opt_options) {
        const options = opt_options || {
            text: 'item',
            callback: (e) => {}
        }
        const item = document.createElement('div')
        item.className = 'ol-contentmenu-item'
        item.text = options.text
        item.onclick = options.callback
        return item
    }

    open(pixel, options) {
        this.object_ = options
        this.menu_.style.visibility = 'visible'
        this.menu_.style.position = 'absolute'
        this.menu_.style.zIndex = 99999
        this.menu_.style.top = pixel[1] + 'px'
        this.menu_.style.left = pixel[0] + 'px'
    }

    close() {
        this.menu_.style.visibility = 'hidden'
    }
}

/**
 * 编辑功能
 */
class ExampleModify {
    map = null
    end = function (event, coordinates) {}
    star = function (event, coordinates) {}
    layers = []
    interaction = []

    constructor(map, layers, end, star) {
        this.map = map
        this.end = end
        this.star = star
        this.layers = layers
    }

    /**
     * 初始化编辑
     */
    start() {
        for (let i in this.layers) {
            this.appendModify(this.layers[i].feature)
        }
    }

    /**
     * 添加对象编辑
     * @param {ol.Feature} feature
     */
    appendModify(feature) {
        let selected = feature.getStyle()
        var modify = new Modify({
            features: new Collection([feature]),
            pixelTolerance: 50,
            style: selected
        })
        modify.on('modifyend', (e) => {
            let geom = e.features.item(0).getGeometry()
            let type = geom.getType()
            let point = geom.getCoordinates()

            this.end(e, point, e.features.item(0))
        })
        modify.on('modifystart', (e) => {
            let geom = e.features.item(0).getGeometry()
            let type = geom.getType()
            let point = geom.getCoordinates()
            if (this.star) {
                this.star(e, point, e.features.item(0))
            }
        })

        this.map.addInteraction(modify)
        this.interaction.push(modify)
    }

    stop() {
        for (let i in this.interaction) {
            this.map.removeInteraction(this.interaction[i])
        }
        this.interaction = []
    }
}

/**
 * 设置要素样式
 * @param {Object} object 样式对象
 * @returns
 */
function setStyle(object) {
    let obj = {}
    if (object.image) {
        obj.image = new Icon(object.image)
    }
    if (object.fill) {
        obj.fill = new Fill(object.fill)
    }
    if (object.stroke) {
        obj.stroke = new Stroke(object.stroke)
    }
    if (object.text) {
        obj.text = object.text
        if (obj.text.fill) {
            obj.text.fill = new Fill(object.text.fill)
        }
        if (object.text.stroke) {
            obj.text.stroke = new Stroke(object.text.stroke)
        }
        if (object.text.backgroundStroke) {
            obj.text.backgroundStroke = new Stroke(object.text.backgroundStroke)
        }
        if (object.text.backgroundFill) {
            obj.text.backgroundFill = new Fill(object.text.backgroundFill)
        }
        obj.text = new Text(object.text)
    }

    return obj
}
